home *** CD-ROM | disk | FTP | other *** search
/ Aminet 1 (Walnut Creek) / Aminet - June 1993 [Walnut Creek].iso / aminet / util / gnu / emacs_src_18_58.lha / emacs-18.58 / src / amiga_dump.c < prev    next >
C/C++ Source or Header  |  1992-08-17  |  20KB  |  722 lines

  1. #include <exec/types.h>
  2. #include <fcntl.h>
  3. #include <stdio.h>
  4. #include <assert.h>
  5. #include <proto/dos.h>
  6. #include <internal/messages.h>
  7. #include "config.h"
  8. #include "lisp.h"
  9. #include "buffer.h"
  10. #include "regex.h"
  11. #include "amiga.h"
  12. #include "dispextern.h"
  13. #include "termchar.h"
  14.  
  15. #define RANGE(ptr, s, e) ((char *)ptr >= (char *)s && (char *)ptr < (char *)e)
  16. #define HUNK_POS (VALBITS - 3)
  17. #define HUNK_MASK (7 << HUNK_POS)
  18. #define HUNK_CODE (0 << HUNK_POS)
  19. #define HUNK_DATA (1 << HUNK_POS)
  20. #define HUNK_BSS (2 << HUNK_POS)
  21. #define HUNK_MALLOC (3 << HUNK_POS)
  22. #define HUNK_PURE (4 << HUNK_POS)
  23. #define ARRAY_MARK_FLAG ((MARKBIT >> 1) & ~MARKBIT)
  24.  
  25. void *far first_fn = first_function, *far last_fn = last_function;
  26.  
  27. extern int *pure, puresize;
  28. extern struct gcpro *gcprolist;
  29.  
  30. extern Lisp_Object *staticvec[];
  31. extern int staticidx;
  32. extern struct cons_block *cons_block;
  33. extern struct Lisp_Cons *cons_free_list;
  34. extern struct Lisp_Vector *all_vectors;
  35. extern struct symbol_block *symbol_block;
  36. extern struct Lisp_Symbol *symbol_free_list;
  37. extern struct marker_block *marker_block;
  38. extern struct Lisp_Marker *marker_free_list;
  39.  
  40. struct string_block_head
  41.   {
  42.     struct string_block_head *next, *prev;
  43.     int pos;
  44.   };
  45. extern struct string_block_head *current_string_block;
  46. extern struct string_block_head *first_string_block;
  47. extern struct string_block_head *large_string_blocks;
  48. extern char *kbd_macro_buffer, *read_buffer, *chars_wasted, *copybuf;
  49. extern struct minibuf_save_data *minibuf_save_vector;
  50. extern struct re_pattern_buffer searchbuf;
  51. extern int *ILcost, *DLcost, *ILncost, *DLncost;
  52. extern Lisp_Object MouseMap, global_map, Vglobal_map, Vesc_map, Vctl_x_map;
  53. extern Lisp_Object Qvariable_documentation, selected_window;
  54.  
  55. extern char *callint_argfuns[];
  56.  
  57. static void *dump_malloc(int size)
  58. {
  59.   void *new = malloc(size);
  60.  
  61.   if (!new) no_memory();
  62.  
  63.   return new;
  64. }
  65.  
  66. static void bailout(char *fn)
  67. {
  68.   if (fn) _message("%s isn't a dump file for this version of Emacs, aborting", fn);
  69.   else _message("Dump file isn't for this version of Emacs, aborting");
  70.  
  71.   /* We are in deep trouble, as all our variables are potentially corrupt */
  72.   /* Therefore, no cleanup is possible */
  73.   /* Remove cleanup routines */
  74.   onexit(0);
  75.   /* However, the library & the memory allocation should be ok, so
  76.      we can exit reasonably */
  77.   _fail("Some system resources may have been lost");
  78. }
  79.  
  80. static void *hunk_pointer(void *ptr)
  81. {
  82.     if (!ptr) return ptr;
  83.  
  84.     if (RANGE(ptr, first_fn, last_fn))
  85.     return (void *)(HUNK_CODE | (char *)ptr - (char *)first_fn);
  86.     else if (RANGE(ptr, &first_data, &last_data))
  87.     return (void *)(HUNK_DATA | (char *)ptr - (char *)&first_data);
  88.     else if (RANGE(ptr, &first_bss, &last_bss))
  89.     return (void *)(HUNK_BSS | (char *)ptr - (char *)&first_bss);
  90.     else if (RANGE(ptr, malloc_hunk, malloc_hunk + malloc_hunk_size))
  91.     return (void *)(HUNK_MALLOC | (char *)ptr - malloc_hunk);
  92.     else if (RANGE(ptr, pure, (char *)pure + puresize))
  93.     return (void *)(HUNK_PURE | (char *)ptr - (char *)pure);
  94.     else bailout(0);
  95. }
  96.  
  97. static Lisp_Object hunk_lispptr(Lisp_Object *objptr, Lisp_Object val)
  98. {
  99.     int type = val & ~VALMASK;
  100.     void *ptr = (void *)XPNTR(val);
  101.  
  102.     if (RANGE(ptr, first_fn, last_fn))
  103.     return type | HUNK_CODE | (char *)ptr - (char *)first_fn;
  104.     else if (RANGE(ptr, &first_data, &last_data))
  105.     return type | HUNK_DATA | (char *)ptr - (char *)&first_data;
  106.     else if (RANGE(ptr, &first_bss, &last_bss))
  107.     return type | HUNK_BSS | (char *)ptr - (char *)&first_bss;
  108.     else if (RANGE(ptr, pure, (char *)pure + puresize))
  109.     return type | HUNK_PURE | (char *)ptr - (char *)pure;
  110.     else if (RANGE(ptr, malloc_hunk, malloc_hunk + malloc_hunk_size))
  111.     return type | HUNK_MALLOC | (char *)ptr - malloc_hunk;
  112.     else bailout(0);
  113. }
  114.  
  115. static void patch_pointers ();
  116.  
  117. static void patch_buffer (buf)
  118.      Lisp_Object buf;
  119. {
  120.   Lisp_Object tem;
  121.   register struct buffer *buffer = XBUFFER (buf);
  122.   register Lisp_Object *ptr;
  123.  
  124.   buffer->text.beg = hunk_pointer (buffer->text.beg);
  125.   patch_pointers (&buffer->markers);
  126.  
  127.   /* This is the buffer's markbit */
  128.   patch_pointers (&buffer->name);
  129.   XMARK (buffer->name);
  130.  
  131.   for (ptr = &buffer->name + 1;
  132.        (char *)ptr < (char *)buffer + sizeof (struct buffer);
  133.        ptr++)
  134.     patch_pointers (ptr);
  135. }
  136.  
  137. static void patch_pointers (objptr)
  138.      Lisp_Object *objptr;
  139. {
  140.   register Lisp_Object obj;
  141.  
  142.   obj = *objptr;
  143.   XUNMARK (obj);
  144.  
  145.  
  146.  loop:
  147.  
  148.   switch (XGCTYPE (obj))
  149.     {
  150.     case Lisp_String:
  151.       *objptr = hunk_lispptr(objptr, *objptr);
  152.       break;
  153.  
  154.     case Lisp_Vector:
  155.     case Lisp_Window:
  156.     case Lisp_Process:
  157.     case Lisp_Window_Configuration:
  158.       *objptr = hunk_lispptr(objptr, *objptr);
  159.       {
  160.     register struct Lisp_Vector *ptr = XVECTOR (obj);
  161.     register int size = ptr->size;
  162.     register int i;
  163.  
  164.     if (size & ARRAY_MARK_FLAG) break;   /* Already marked */
  165.     ptr->size |= ARRAY_MARK_FLAG; /* Else mark it */
  166.     for (i = 0; i < size; i++)     /* and then mark its elements */
  167.       patch_pointers (&ptr->contents[i]);
  168.       }
  169.       break;
  170.  
  171.     case Lisp_Symbol:
  172.       *objptr = hunk_lispptr(objptr, *objptr);
  173.       {
  174.     register struct Lisp_Symbol *ptr = XSYMBOL (obj);
  175.     struct Lisp_Symbol *ptrx;
  176.  
  177.     if (XMARKBIT (ptr->plist)) break;
  178.     XMARK (ptr->plist);
  179.     XSETTYPE (*(Lisp_Object *) &ptr->name, Lisp_String);
  180.     patch_pointers (&ptr->name);
  181.     patch_pointers ((Lisp_Object *) &ptr->value);
  182.     patch_pointers (&ptr->function);
  183.     patch_pointers (&ptr->plist);
  184.     objptr = (Lisp_Object *)&ptr->next;
  185.     ptr = ptr->next;
  186.     if (ptr)
  187.       {
  188.         ptrx = ptr;        /* Use pf ptrx avoids compiler bug on Sun */
  189.         XSETSYMBOL (obj, ptrx);
  190.         goto loop;
  191.       }
  192.       }
  193.       break;
  194.  
  195.     case Lisp_Marker: {
  196.     struct Lisp_Marker *ptr = XMARKER (obj);
  197.  
  198.     *objptr = hunk_lispptr(objptr, *objptr);
  199.     if (XMARKBIT (ptr->chain)) break;
  200.     XMARK (ptr->chain);
  201.     ptr->buffer = hunk_pointer (ptr->buffer);
  202.     patch_pointers (&ptr->chain);
  203.     break;
  204.     }
  205.  
  206.     case Lisp_Cons:
  207.     case Lisp_Buffer_Local_Value:
  208.     case Lisp_Some_Buffer_Local_Value:
  209.       *objptr = hunk_lispptr(objptr, *objptr);
  210.       {
  211.     register struct Lisp_Cons *ptr = XCONS (obj);
  212.     if (XMARKBIT (ptr->car)) break;
  213.     XMARK (ptr->car);
  214.     patch_pointers (&ptr->car);
  215.     objptr = &ptr->cdr;
  216.     obj = ptr->cdr;
  217.     goto loop;
  218.       }
  219.  
  220.     case Lisp_Buffer:
  221.       *objptr = hunk_lispptr(objptr, *objptr);
  222.       if (!XMARKBIT (XBUFFER (obj)->name))
  223.     patch_buffer (obj);
  224.       break;
  225.  
  226.     case Lisp_Subr: {
  227.     struct Lisp_Subr *subr = XSUBR(obj);
  228.  
  229.     *objptr = hunk_lispptr(objptr, *objptr);
  230.     if (subr->min_args & 0x8000) break;
  231.     subr->min_args |= 0x8000;
  232.     subr->function = hunk_pointer(subr->function);
  233.     subr->symbol_name = hunk_pointer(subr->symbol_name);
  234.     subr->prompt = hunk_pointer(subr->prompt);
  235.     if ((long)subr->doc >= 0) /* Make sure that not a doc offset */
  236.         subr->doc = hunk_pointer(subr->doc);
  237.     break;
  238.     }
  239.  
  240.     case Lisp_Int:
  241.     case Lisp_Void:
  242.     case Lisp_Buffer_Objfwd: break;
  243.  
  244.     case Lisp_Intfwd:
  245.     case Lisp_Boolfwd:
  246.     case Lisp_Objfwd:
  247.     case Lisp_Internal_Stream:
  248.       *objptr = hunk_lispptr(objptr, *objptr);
  249.     /* Don't bother with Lisp_Buffer_Objfwd,
  250.        since all markable slots in current buffer marked anyway.  */
  251.     /* Don't need to do Lisp_Objfwd, since the places they point
  252.        are protected with staticpro.  */
  253.       break;
  254.  
  255.     default:
  256.       abort ();
  257.     }
  258. }
  259.  
  260. static void patch_chain(void **ptr, int offset)
  261. {
  262.     while (*ptr)
  263.     {
  264.     void **next = (void **)((char *)*ptr + offset);
  265.  
  266.     *ptr = hunk_pointer(*ptr);
  267.     ptr = next;
  268.     }
  269. }
  270.  
  271. static void patch(void)
  272. {
  273.     int i;
  274.     struct string_block_head *sptr;
  275.     struct buffer *bptr;
  276.     struct mem_header *mem;
  277.  
  278.     for (i = 0; i < staticidx; i++)
  279.     {
  280.     if (!XMARKBIT(*staticvec[i]))
  281.     {
  282.         patch_pointers(staticvec[i]);
  283.         XMARK(*staticvec[i]);
  284.     }
  285.     staticvec[i] = hunk_pointer(staticvec[i]);
  286.     }
  287.  
  288.     /* Patch all the pointers normally used before a dump ! */
  289.     patch_chain((void **)&cons_block, 0);
  290.     patch_chain((void **)&cons_free_list, 0);
  291.  
  292.     patch_chain((void **)&all_vectors, 4);
  293.  
  294.     patch_chain((void **)&symbol_block, 0);
  295.     patch_chain((void **)&symbol_free_list, 4);
  296.  
  297.     patch_chain((void **)&marker_block, 0);
  298.     patch_chain((void **)&marker_free_list, 4);
  299.  
  300.     /* Strings are lots of fun */
  301.     patch_chain((void **)&large_string_blocks, 0);
  302.     sptr = first_string_block;
  303.     while (sptr)
  304.     {
  305.     struct string_block *next = sptr->next;
  306.  
  307.     if (sptr->next) sptr->next = hunk_pointer(sptr->next);
  308.     if (sptr->prev) sptr->prev = hunk_pointer(sptr->prev);
  309.     sptr = next;
  310.     }
  311.     first_string_block = hunk_pointer(first_string_block);
  312.     current_string_block = hunk_pointer(current_string_block);
  313.  
  314.     /* More fun with buffers */
  315.     bptr = all_buffers;
  316.     if (bptr)
  317.     {
  318.     while (bptr->next)
  319.     {
  320.         struct buffer *next = bptr->next;
  321.  
  322.         bptr->next = hunk_pointer(bptr->next);
  323.         bptr = next;
  324.     }
  325.     }
  326.     all_buffers = hunk_pointer(all_buffers);
  327.     current_buffer = hunk_pointer(current_buffer);
  328.  
  329.     kbd_macro_buffer = hunk_pointer(kbd_macro_buffer);
  330.     minibuf_save_vector = hunk_pointer(minibuf_save_vector);
  331.     searchbuf.buffer = hunk_pointer(searchbuf.buffer);
  332.     searchbuf.fastmap = hunk_pointer(searchbuf.fastmap);
  333.     specpdl = hunk_pointer(specpdl);
  334.     read_buffer = hunk_pointer(read_buffer);
  335.  
  336.     MouseMap = hunk_lispptr(&MouseMap, MouseMap);
  337.     global_map = hunk_lispptr(&global_map, global_map);
  338.     Vglobal_map = hunk_lispptr(&Vglobal_map, Vglobal_map);
  339.     Vesc_map = hunk_lispptr(&Vesc_map, Vesc_map);
  340.     Vctl_x_map = hunk_lispptr(&Vctl_x_map, Vctl_x_map);
  341.  
  342.     Qvariable_documentation = hunk_lispptr(&Qvariable_documentation, Qvariable_documentation);
  343.     selected_window = hunk_lispptr(&selected_window, selected_window);
  344.  
  345.     mem = free_list;
  346.     free_list = hunk_pointer(free_list);
  347.     while (mem)
  348.     {
  349.     struct mem_header *next = mem->next;
  350.  
  351.     mem->prev = hunk_pointer(mem->prev);
  352.     mem->next = hunk_pointer(mem->next);
  353.     mem = next;
  354.     }
  355.  
  356.     for (i = 0; i <= 4; i++)
  357.       callint_argfuns[i] = hunk_pointer(callint_argfuns[i]);
  358. }
  359.  
  360. static dump(char *fn)
  361. {
  362.     BPTR fd;
  363.     long size;
  364.  
  365.     fd = Open(fn, MODE_NEWFILE);
  366.     if (!fd)
  367.       {
  368.         static void unpatch();
  369.  
  370.         unpatch();
  371.         _fail("emacs hasn't been dumped (%s missing)", fn);
  372.       }
  373.  
  374.     Write(fd, (char *)&puresize, sizeof puresize);
  375.     Write(fd, (char *)&malloc_hunk_size, sizeof malloc_hunk_size);
  376.     Write(fd, (char *)&first_data, (char *)&last_data - (char *)&first_data);
  377.     Write(fd, (char *)&first_bss, (char *)&last_bss - (char *)&first_bss);
  378.     Write(fd, (char *)pure, puresize);
  379.     Write(fd, (char *)malloc_hunk, malloc_hunk_size);
  380.     Write(fd, (char *)&staticidx, sizeof staticidx);
  381.     Write(fd, (char *)staticvec, staticidx * sizeof(Lisp_Object *));
  382.     size = (char *)last_fn - (char *)first_fn;
  383.     Write(fd, (char *)&size, sizeof size);
  384.  
  385.     Close(fd);
  386. }
  387.  
  388. static void *make_pointer(void *ptr)
  389. {
  390.     int hunk = (long)ptr & HUNK_MASK;
  391.     int offset = (long)ptr & (VALMASK & ~HUNK_MASK);
  392.  
  393.     if (!ptr) return 0;
  394.  
  395.     if (hunk == HUNK_CODE) return (char *)first_fn + offset;
  396.     if (hunk == HUNK_DATA) return (char *)&first_data + offset;
  397.     if (hunk == HUNK_BSS) return (char *)&first_bss + offset;
  398.     if (hunk == HUNK_PURE) return (char *)pure + offset;
  399.     if (hunk == HUNK_MALLOC) return malloc_hunk + offset;
  400.     assert(0);
  401. }
  402.  
  403. static Lisp_Object make_lispptr(Lisp_Object *objptr, Lisp_Object obj)
  404. {
  405.     long val = XUINT(obj);
  406.     int hunk = val & HUNK_MASK;
  407.     int offset = val & ~HUNK_MASK;
  408.     char *ptr;
  409.  
  410.     if (hunk == HUNK_CODE) ptr = (char *)first_fn + offset;
  411.     else if (hunk == HUNK_DATA) ptr = (char *)&first_data + offset;
  412.     else if (hunk == HUNK_BSS) ptr = (char *)&first_bss + offset;
  413.     else if (hunk == HUNK_PURE) ptr = (char *)pure + offset;
  414.     else if (hunk == HUNK_MALLOC) ptr = malloc_hunk + offset;
  415.     else assert(0);
  416.  
  417.     XSETPNTR(obj, (long)ptr);
  418.     return obj;
  419. }
  420.  
  421. static void unpatch_pointers ();
  422.  
  423. static void unpatch_buffer (buf)
  424.      Lisp_Object buf;
  425. {
  426.   Lisp_Object tem;
  427.   register struct buffer *buffer = XBUFFER (buf);
  428.   register Lisp_Object *ptr;
  429.  
  430.   buffer->text.beg = make_pointer (buffer->text.beg);
  431.   unpatch_pointers (&buffer->markers);
  432.  
  433.   /* This is the buffer's markbit */
  434.   XUNMARK (buffer->name);
  435.   unpatch_pointers (&buffer->name);
  436.  
  437.   for (ptr = &buffer->name + 1;
  438.        (char *)ptr < (char *)buffer + sizeof (struct buffer);
  439.        ptr++)
  440.     unpatch_pointers (ptr);
  441. }
  442.  
  443. static void unpatch_pointers (objptr)
  444.      Lisp_Object *objptr;
  445. {
  446.   register Lisp_Object obj;
  447.  
  448.   obj = *objptr;
  449.   XUNMARK (obj);
  450.  
  451.  
  452.  loop:
  453.  
  454.   switch (XGCTYPE (obj))
  455.     {
  456.     case Lisp_String:
  457.       *objptr = make_lispptr(objptr, *objptr);
  458.       break;
  459.  
  460.     case Lisp_Vector:
  461.     case Lisp_Window:
  462.     case Lisp_Process:
  463.     case Lisp_Window_Configuration:
  464.       obj = *objptr = make_lispptr(objptr, *objptr);
  465.       {
  466.     register struct Lisp_Vector *ptr = XVECTOR (obj);
  467.     register int size;
  468.     register int i;
  469.  
  470.     if (!(ptr->size & ARRAY_MARK_FLAG)) break;   /* Already unmarked */
  471.     size = ptr->size &= ~ARRAY_MARK_FLAG; /* Else unmark it */
  472.     for (i = 0; i < size; i++)     /* and then unmark its elements */
  473.       unpatch_pointers (&ptr->contents[i]);
  474.       }
  475.       break;
  476.  
  477.     case Lisp_Symbol:
  478.       obj = *objptr = make_lispptr(objptr, *objptr);
  479.       {
  480.     register struct Lisp_Symbol *ptr = XSYMBOL (obj);
  481.     struct Lisp_Symbol *ptrx;
  482.  
  483.     if (!XMARKBIT (ptr->plist)) break;
  484.     XUNMARK (ptr->plist);
  485.     unpatch_pointers (&ptr->name);
  486.     ptr->name = XSTRING (*(Lisp_Object *)&ptr->name);
  487.     unpatch_pointers ((Lisp_Object *) &ptr->value);
  488.     unpatch_pointers (&ptr->function);
  489.     unpatch_pointers (&ptr->plist);
  490.     objptr = (Lisp_Object *)&ptr->next;
  491.     ptr = ptr->next;
  492.     if (ptr)
  493.       {
  494.         ptrx = ptr;        /* Use pf ptrx avoids compiler bug on Sun */
  495.         XSET (obj, Lisp_Symbol, ptrx);
  496.         goto loop;
  497.       }
  498.       }
  499.       break;
  500.  
  501.     case Lisp_Marker: {
  502.     struct Lisp_Marker *ptr;
  503.  
  504.     obj = *objptr = make_lispptr(objptr, *objptr);
  505.     ptr = XMARKER (obj);
  506.     if (!XMARKBIT (ptr->chain)) break;
  507.     XUNMARK (ptr->chain);
  508.     ptr->buffer = make_pointer (ptr->buffer);
  509.     unpatch_pointers (&ptr->chain);
  510.     break;
  511.     }
  512.  
  513.     case Lisp_Cons:
  514.     case Lisp_Buffer_Local_Value:
  515.     case Lisp_Some_Buffer_Local_Value:
  516.       obj = *objptr = make_lispptr(objptr, *objptr);
  517.       {
  518.     register struct Lisp_Cons *ptr = XCONS (obj);
  519.     if (!XMARKBIT (ptr->car)) break;
  520.     XUNMARK (ptr->car);
  521.     unpatch_pointers (&ptr->car);
  522.     objptr = &ptr->cdr;
  523.     obj = ptr->cdr;
  524.     goto loop;
  525.       }
  526.  
  527.     case Lisp_Buffer:
  528.       obj = *objptr = make_lispptr(objptr, *objptr);
  529.       if (XMARKBIT (XBUFFER (obj)->name))
  530.     unpatch_buffer (obj);
  531.       break;
  532.  
  533.     case Lisp_Subr: {
  534.     struct Lisp_Subr *subr;
  535.  
  536.     obj = *objptr = make_lispptr(objptr, *objptr);
  537.     subr = XSUBR(obj);
  538.     if (!(subr->min_args & 0x8000)) break;
  539.     subr->min_args &= ~0x8000;
  540.     subr->function = make_pointer(subr->function);
  541.     subr->symbol_name = make_pointer(subr->symbol_name);
  542.     subr->prompt = make_pointer(subr->prompt);
  543.     if ((long)subr->doc >= 0) /* Make sure that not a doc offset */
  544.         subr->doc = make_pointer(subr->doc);
  545.     break;
  546.     }
  547.  
  548.     case Lisp_Int:
  549.     case Lisp_Void:
  550.     case Lisp_Buffer_Objfwd: break;
  551.  
  552.     case Lisp_Intfwd:
  553.     case Lisp_Boolfwd:
  554.     case Lisp_Objfwd:
  555.     case Lisp_Internal_Stream:
  556.       *objptr = make_lispptr(objptr, *objptr);
  557.     /* Don't bother with Lisp_Buffer_Objfwd,
  558.        since all markable slots in current buffer marked anyway.  */
  559.     /* Don't need to do Lisp_Objfwd, since the places they point
  560.        are protected with staticpro.  */
  561.       break;
  562.  
  563.     default:
  564.       abort ();
  565.     }
  566. }
  567.  
  568. static void unpatch_chain(void **ptr, int offset)
  569. {
  570.     while (*ptr)
  571.     {
  572.     *ptr = make_pointer(*ptr);
  573.     ptr = (void **)((char *)*ptr + offset);
  574.     }
  575. }
  576.  
  577. /* Reconstructs the addresses that were patched */
  578. static void unpatch(void)
  579. {
  580.     int fd, i;
  581.     struct string_block_head *sptr;
  582.     struct buffer *bptr;
  583.     struct mem_header *mem;
  584.  
  585.     for (i = 0; i < staticidx; i++)
  586.     {
  587.     staticvec[i] = make_pointer(staticvec[i]);
  588.     if (XMARKBIT(*staticvec[i]))
  589.     {
  590.         XUNMARK(*staticvec[i]);
  591.         unpatch_pointers(staticvec[i]);
  592.     }
  593.     }
  594.  
  595.     /* Unpatch all the pointers normally used before a dump ! */
  596.     unpatch_chain((void **)&cons_block, 0);
  597.     unpatch_chain((void **)&cons_free_list, 0);
  598.  
  599.     unpatch_chain((void **)&all_vectors, 4);
  600.  
  601.     unpatch_chain((void **)&symbol_block, 0);
  602.     unpatch_chain((void **)&symbol_free_list, 4);
  603.  
  604.     unpatch_chain((void **)&marker_block, 0);
  605.     unpatch_chain((void **)&marker_free_list, 4);
  606.  
  607.     /* Strings are lots of fun */
  608.     unpatch_chain((void **)&large_string_blocks, 0);
  609.     sptr = first_string_block = make_pointer(first_string_block);
  610.     current_string_block = make_pointer(current_string_block);
  611.     while (sptr)
  612.     {
  613.     if (sptr->next) sptr->next = make_pointer(sptr->next);
  614.     if (sptr->prev) sptr->prev = make_pointer(sptr->prev);
  615.     sptr = sptr->next;
  616.     }
  617.  
  618.     /* More fun with buffers */
  619.     bptr = all_buffers = make_pointer(all_buffers);
  620.     if (bptr)
  621.     {
  622.     while (bptr->next)
  623.     {
  624.         bptr->next = make_pointer(bptr->next);
  625.         bptr = bptr->next;
  626.     }
  627.     }
  628.     current_buffer = make_pointer(current_buffer);
  629.  
  630.     kbd_macro_buffer = make_pointer(kbd_macro_buffer);
  631.     minibuf_save_vector = make_pointer(minibuf_save_vector);
  632.     searchbuf.buffer = make_pointer(searchbuf.buffer);
  633.     searchbuf.fastmap = make_pointer(searchbuf.fastmap);
  634.     specpdl = make_pointer(specpdl);
  635.     read_buffer = make_pointer(read_buffer);
  636.  
  637.     MouseMap = make_lispptr(&MouseMap, MouseMap);
  638.     global_map = make_lispptr(&global_map, global_map);
  639.     Vglobal_map = make_lispptr(&Vglobal_map, Vglobal_map);
  640.     Vesc_map = make_lispptr(&Vesc_map, Vesc_map);
  641.     Vctl_x_map = make_lispptr(&Vctl_x_map, Vctl_x_map);
  642.  
  643.     Qvariable_documentation = make_lispptr(&Qvariable_documentation, Qvariable_documentation);
  644.     selected_window = make_lispptr(&selected_window, selected_window);
  645.  
  646.     free_list = make_pointer(free_list);
  647.     mem = free_list;
  648.     while (mem)
  649.     {
  650.     mem->prev = make_pointer(mem->prev);
  651.     mem->next = make_pointer(mem->next);
  652.     mem = mem->next;
  653.     }
  654.  
  655.     for (i = 0; i <= 4; i++)
  656.       callint_argfuns[i] = make_pointer(callint_argfuns[i]);
  657. }
  658.  
  659. static undump(char *fn)
  660. {
  661.   BPTR fd;
  662.   long code_size;
  663.   char *_malloc_hunk;
  664.   int *_pure;
  665.   /*extern struct Library *FifoBase;
  666.   struct Library *_FifoBase = FifoBase;*/
  667.  
  668.   fd = Open(fn, MODE_OLDFILE);
  669.   if (!fd) return 0;
  670.  
  671.   Read(fd, (char *)&puresize, sizeof puresize);
  672.   Read(fd, (char *)&malloc_hunk_size, sizeof malloc_hunk_size);
  673.   _pure = dump_malloc(puresize);
  674.   _malloc_hunk = dump_malloc(malloc_hunk_size + pre_alloc);
  675.   Read(fd, (char *)&first_data, (char *)&last_data - (char *)&first_data);
  676.   Read(fd, (char *)&first_bss, (char *)&last_bss - (char *)&first_bss);
  677.   Read(fd, (char *)_pure, puresize);
  678.   Read(fd, (char *)_malloc_hunk, malloc_hunk_size);
  679.   Read(fd, (char *)&staticidx, sizeof staticidx);
  680.   Read(fd, (char *)staticvec, staticidx * sizeof(Lisp_Object *));
  681.   /*FifoBase = _FifoBase;*/
  682.   if (Read(fd, (char *)&code_size, sizeof code_size) != sizeof code_size ||
  683.       code_size != (char *)last_fn - (char *)first_fn)
  684.     bailout(fn);
  685.  
  686.   Close(fd);
  687.   malloc_hunk = _malloc_hunk;
  688.   pure = _pure;
  689.   return 1;
  690. }
  691.  
  692. void map_out_data(char *fn)
  693. {
  694.     if (amiga_initialized) error("You can only dump once !");
  695.     Fgarbage_collect();
  696.  
  697.     patch();
  698.     dump(fn);
  699.     unpatch();
  700.     amiga_initialized = 1;
  701. }
  702.  
  703. void map_in_data(int load)
  704. {
  705.     if (load && undump("GNUEmacs:etc/EMACS-DATA"))
  706.     {
  707.     unpatch();
  708.     current_screen = new_screen = temp_screen = 0;
  709.     message_buf = 0;
  710.     chars_wasted = copybuf = 0;
  711.     DC_ICcost = 0;
  712.     ILcost = DLcost = ILncost = DLncost = 0;
  713.     initialized = amiga_initialized = 1;
  714.     }
  715.     else
  716.       {
  717.     malloc_hunk = dump_malloc(malloc_hunk_size + pre_alloc);
  718.     pure = dump_malloc(puresize);
  719.       }
  720.     amiga_undump_reinit();
  721. }
  722.